/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package pedigreereconstruction;

import distribution.*;
import java.io.*;
import java.util.*;
import java.util.logging.Level;
import java.util.logging.Logger;
import relationships.*;

/**
 *
 * @author arthiramachandran
 */
public class GoldStandard {

    static Pedigree pedigree = new ProbabilisticPedigree();
    public static ArrayList<HashMap<String, ProbabilisticRelationship>> relationships =
            new ArrayList<HashMap<String, ProbabilisticRelationship>>(5);
    public static HashMap<String, Individual> individuals =
            new HashMap<String, Individual>();
    private static RelationshipDistribution parent_child = null, grandparent_grandchild =
            null, siblings = null, halfsiblings = null, unrelated = null;
    public static final int PARENT_CHILD = 0, GRANDPARENT_GRANDCHILD = 1, SIBLINGS =
            2, HALF_SIBLINGS = 3, UNRELATED = 4;
    public static final int GP_P_GC = 0, P_C_P = 1, C_P_C = 2, P_S_C = 3, S_S_S =
            4;

    public static void main(String args[]) {
        /**
         * Read in soap.fam file
         * create big pedigree from it
         * get subgraphs of size k
         */
        createPedigreeFromFamFile("Soapv2.fam");
        //createPedigreeFromFamFile("test.fam");
        //System.out.println(pedigree.getNumberOfRelationships());
        ArrayList<Pedigree> subPedigrees = new ArrayList<Pedigree>();
        subPedigrees = getSubPedigreesOfDegreeD(4);

        for (Pedigree p : subPedigrees) {
            System.out.println(p.printGraph());
        }

    }

    private static void initializeRelationshipDistributions() {
        System.out.println(
                "Computing empirical distributions for known relationships");
        /*
         * String p_c_filename = "R Files/parent_child.known.subset.data";
        String gp_gc_filename =
        "R Files/grandparent_grandchild.known.subset.data";
        String s_s_filename = "R Files/siblings.known.subset.data";
        String hs_hs_filename = "R Files/halfsiblings.known.subset.data";
        String unrel_filename = "R Files/background.known.subset.data";
         * 
         */
        String p_c_filename = "R Files/parent_child.known.K-503.pairs.data";
        String gp_gc_filename =
                "R Files/gpgc.known.K-503.pairs.data";
        String s_s_filename = "R Files/sibs.known.K-503.pairs.data";
        String hs_hs_filename = "R Files/halfsibs.known.K-503.pairs.data";
        String unrel_filename =
                "R Files/previous data/background.known.subset.data";

        try {
            parent_child = new RelationshipDistribution("PARENT_CHILD", false,
                    p_c_filename);
            grandparent_grandchild = new RelationshipDistribution(
                    "GRANDPARENT_GRANDCHILD", false, gp_gc_filename);
            siblings =
                    new RelationshipDistribution("SIBLINGS", true, s_s_filename);
            halfsiblings = new RelationshipDistribution("HALF_SIBLINGS", true,
                    hs_hs_filename);
            unrelated =
                    new RelationshipDistribution("UNRELATED", true, unrel_filename);
        } catch (Exception e) {
            Logger.getLogger(PedigreeReconstruction.class.getName()).log(
                    Level.SEVERE, null, e);
            System.exit(0);
        }
        for (int i = 0; i < 5; i++) // TODO: no constants
        {
            relationships.add(new HashMap<String, ProbabilisticRelationship>());
        }

    }

    public static void createPedigreeFromFamFile(String filename) {
        initializeRelationshipDistributions();

        BufferedReader in = null;
        try {
            in = new BufferedReader(new FileReader(filename));
            String strLine;
            while ((strLine = in.readLine()) != null) {
                //System.out.println(strLine);

                Individual sample = new Individual(strLine.split(" ")[0]);
                Individual dad = new Individual(strLine.split(" ")[1]);
                Individual mom = new Individual(strLine.split(" ")[2]);
                if (sample.id.equals("0") || dad.id.equals("0") || mom.id.equals(
                        "0")) {
                    continue;
                }
                //if (dad.id.startsWith("K-") || mom.id.startsWith("K-")) {
                //    continue;
                //}
                // create pc relationship
                if (!individuals.containsKey(sample.id)) {
                    individuals.put(sample.id, sample);
                }
                if (!individuals.containsKey(dad.id)) {
                    individuals.put(dad.id, dad);
                }
                if (!individuals.containsKey(mom.id)) {
                    individuals.put(mom.id, mom);
                }

                ProbabilisticRelationship rChildDad =
                        newRelationship(dad, sample, PARENT_CHILD, parent_child, PedigreeReconstruction.parent_child);
                ProbabilisticRelationship rChildMom =
                        newRelationship(mom, sample, PARENT_CHILD, parent_child, PedigreeReconstruction.parent_child);

                // add relationship to tree
                pedigree.addRelationship(rChildMom, false);
                pedigree.addRelationship(rChildDad, false);
                //System.out.println(rChildMom + "\t" + rChildDad);
                // also add other relationships for the person?

            }
        } catch (FileNotFoundException ex) {
            Logger.getLogger(GoldStandard.class.getName()).log(Level.SEVERE,
                    null, ex);
        } catch (IOException ex) {
            Logger.getLogger(GoldStandard.class.getName()).log(Level.SEVERE,
                    null, ex);
        } finally {
            try {
                in.close();
            } catch (IOException ex) {
                Logger.getLogger(GoldStandard.class.getName()).log(Level.SEVERE,
                        null, ex);
            }
        }

        System.out.println("True pedigree: ");
        pedigree.printGraph();
    }

    private static ProbabilisticRelationship newRelationship(Individual i1,
            Individual i2, int type, RelationshipDistribution dist,
            RelationshipTypes rel) {
        ProbabilisticRelationship r = new ProbabilisticRelationship(i1, i2, -1,
                -1, -1, rel);
        r.setRelationshipDistribution(dist);
        // TODO: implement with the actual values? Or else get rid of the actual values
        // TODO: implement with proper relationship distributions in file
        String key = "";

        relationships.get(type);
        if (!relationships.get(type).containsKey(key)) {
            relationships.get(type).put(key, r);
        }
        return (r);

    }

    public static ArrayList<Pedigree> getSubPedigreesOfDegreeD(int D) {
        ArrayList<Pedigree> pedigreeList = new ArrayList<Pedigree>();
        // essentially do a DFS
        int count = 0;
        for (Individual i : individuals.values()) {
            System.out.println("SubTree rooted at individual: " + i);
            for (Pedigree sub : pedigree.getSubPedigrees(i, D)) {
                pedigreeList.add(sub);
            }
            count += 1;
            //if (count >= 1) {
            //    break;
            //}
        }
        // Remove duplicates
        ArrayList<Pedigree> finalPedigreeList = new ArrayList<Pedigree>();
        System.out.println("Checking equality");
        System.out.println(pedigreeList.get(3).equals(pedigreeList.get(6)));

        for (Pedigree p : pedigreeList) {
            boolean contained = false;
            for (Pedigree pf : finalPedigreeList) {
                if (pf.equals(p)) {
                    contained = true;
                }
            }
            if (!contained) {
                finalPedigreeList.add(p);
            }
        }
        /*
        for (Pedigree sub : finalPedigreeList) {
        System.out.println("Sub-Pedigree");
        System.out.println(sub.getIndividuals());
        }
         * 
         */

        return pedigreeList;
    }

    // very specific
    static ArrayList<ProbabilisticRelationship> getSubPedigreeRelationshipsOfDegreeD(int D) {
        ArrayList<Pedigree> subPeds = getSubPedigreesOfDegreeD(D);
        ArrayList<ProbabilisticRelationship> rels = new ArrayList<ProbabilisticRelationship>();
        for (Pedigree p : subPeds) {
            Individual i1 = null, i2 = null;
            for (Individual i : p.getIndividuals()) {
                if (p.getNumberOfRelationships(i) <= 1) {
                    if (i1 == null) {
                        i1 = i;
                    } else if (i2 == null) {
                        i2 = i;
                    }
                }
            }
            ProbabilisticRelationship r = new ProbabilisticRelationship(i1, i2, -1, -1, -1, PedigreeReconstruction.unrelated);
            rels.add(r);
        }
        return rels;
    }
}
